"""
IP编辑对话框
"""

import logging
from typing import Dict, Any, Optional
from PyQt5.QtWidgets import (
    QVBoxLayout, QHBoxLayout, QFormLayout, QLineEdit, QComboBox,
    QTextEdit, QGroupBox, QLabel, QGridLayout, QSpacerItem, QSizePolicy, QWidget
)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIntValidator

from src.app.ui.base_dialog import BaseDialog
from src.app.modules.ip.service import IpService
from src.app.modules.ip.utils import IpUtils

logger = logging.getLogger(__name__)

class IpDialog(BaseDialog):
    """IP编辑对话框"""
    
    def __init__(self, parent=None, ip_data: Optional[Dict[str, Any]] = None):
        self.is_edit = ip_data is not None
        self.ip_data = ip_data or {}
        
        # 在调用父类构造函数之前初始化服务
        self.service = IpService()
        self.utils = IpUtils()
        
        title = "编辑IP地址" if self.is_edit else "新增IP地址"
        super().__init__(parent, title=title, width=600, height=500)
        
        if self.is_edit:
            self.load_data()
    
    def create_content_widget(self):
        """创建内容区域"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 基本信息组
        basic_group = self.create_basic_info_group()
        layout.addWidget(basic_group)
        
        # 绑定实体组
        entity_group = self.create_entity_binding_group()
        layout.addWidget(entity_group)
        
        # 附加信息组
        additional_group = self.create_additional_info_group()
        layout.addWidget(additional_group)
        
        return widget
    
    def create_basic_info_group(self) -> QGroupBox:
        """创建基本信息组"""
        group = QGroupBox("基本信息")
        layout = QFormLayout(group)
        
        # IP地址
        self.ip_edit = QLineEdit()
        self.ip_edit.setPlaceholderText("例如: 192.168.1.100")
        layout.addRow("IP地址 *:", self.ip_edit)
        
        # 子网掩码
        self.subnet_mask_edit = QLineEdit()
        self.subnet_mask_edit.setPlaceholderText("例如: 255.255.255.0")
        layout.addRow("子网掩码 *:", self.subnet_mask_edit)
        
        # VLAN
        self.vlan_edit = QLineEdit()
        self.vlan_edit.setPlaceholderText("例如: VLAN100 或 100")
        layout.addRow("VLAN *:", self.vlan_edit)
        
        # 状态
        self.status_combo = QComboBox()
        for option in self.utils.get_status_options():
            self.status_combo.addItem(option['label'], option['value'])
        layout.addRow("状态 *:", self.status_combo)
        
        # 用途
        self.purpose_combo = QComboBox()
        for option in self.utils.get_purpose_options():
            self.purpose_combo.addItem(option['label'], option['value'])
        layout.addRow("用途 *:", self.purpose_combo)
        
        # 分配期限
        self.duration_combo = QComboBox()
        for option in self.utils.get_duration_options():
            self.duration_combo.addItem(option['label'], option['value'])
        layout.addRow("分配期限 *:", self.duration_combo)
        
        return group
    
    def create_entity_binding_group(self) -> QGroupBox:
        """创建绑定实体组"""
        group = QGroupBox("绑定实体")
        layout = QGridLayout(group)
        
        # 绑定类型选择
        layout.addWidget(QLabel("绑定类型:"), 0, 0)
        self.binding_type_combo = QComboBox()
        self.binding_type_combo.addItem("不绑定", "")
        self.binding_type_combo.addItem("设备资产", "asset")
        self.binding_type_combo.addItem("操作系统", "os")
        self.binding_type_combo.addItem("业务系统", "system")
        self.binding_type_combo.addItem("中间件", "middleware")
        self.binding_type_combo.addItem("带外管理", "oob")
        self.binding_type_combo.currentTextChanged.connect(self.on_binding_type_changed)
        layout.addWidget(self.binding_type_combo, 0, 1, 1, 2)
        
        # 绑定ID
        layout.addWidget(QLabel("绑定ID:"), 1, 0)
        self.binding_id_edit = QLineEdit()
        self.binding_id_edit.setPlaceholderText("选择绑定类型后输入对应ID")
        self.binding_id_edit.setEnabled(False)
        layout.addWidget(self.binding_id_edit, 1, 1, 1, 2)
        
        # 添加提示
        hint_label = QLabel("提示: IP地址只能绑定到一个实体")
        hint_label.setStyleSheet("color: #666666; font-size: 10px;")
        layout.addWidget(hint_label, 2, 0, 1, 3)
        
        return group
    
    def create_additional_info_group(self) -> QGroupBox:
        """创建附加信息组"""
        group = QGroupBox("附加信息")
        layout = QFormLayout(group)
        
        # 操作系统名称
        self.os_name_edit = QLineEdit()
        self.os_name_edit.setPlaceholderText("例如: CentOS 7.9")
        layout.addRow("操作系统名称:", self.os_name_edit)
        
        # 主机名
        self.hostname_edit = QLineEdit()
        self.hostname_edit.setPlaceholderText("例如: web-server-01")
        layout.addRow("主机名:", self.hostname_edit)
        
        # 描述
        self.description_edit = QTextEdit()
        self.description_edit.setPlaceholderText("输入IP地址的详细描述...")
        self.description_edit.setMaximumHeight(80)
        layout.addRow("描述:", self.description_edit)
        
        return group
    
    def on_binding_type_changed(self):
        """绑定类型变化事件"""
        binding_type = self.binding_type_combo.currentData()
        
        if binding_type:
            self.binding_id_edit.setEnabled(True)
            self.binding_id_edit.clear()
            
            # 根据类型设置不同的提示
            hints = {
                'asset': '输入设备资产ID (例如: ASSET001)',
                'os': '输入操作系统ID (例如: OS001)',
                'system': '输入业务系统ID (例如: SYS001)',
                'middleware': '输入中间件ID (例如: MW001)',
                'oob': '输入带外管理ID (例如: OOB001)'
            }
            
            hint = hints.get(binding_type, '输入对应的实体ID')
            self.binding_id_edit.setPlaceholderText(hint)
        else:
            self.binding_id_edit.setEnabled(False)
            self.binding_id_edit.clear()
            self.binding_id_edit.setPlaceholderText("选择绑定类型后输入对应ID")
    
    def load_data(self):
        """加载数据"""
        try:
            # 基本信息
            self.ip_edit.setText(self.ip_data.get('ip', ''))
            self.subnet_mask_edit.setText(self.ip_data.get('subnet_mask', ''))
            self.vlan_edit.setText(self.ip_data.get('vlan', ''))
            
            # 状态
            status = self.ip_data.get('status', '')
            for i in range(self.status_combo.count()):
                if self.status_combo.itemData(i) == status:
                    self.status_combo.setCurrentIndex(i)
                    break
            
            # 用途
            purpose = self.ip_data.get('purpose', '')
            for i in range(self.purpose_combo.count()):
                if self.purpose_combo.itemData(i) == purpose:
                    self.purpose_combo.setCurrentIndex(i)
                    break
            
            # 分配期限
            duration = self.ip_data.get('allocation_duration', '')
            for i in range(self.duration_combo.count()):
                if self.duration_combo.itemData(i) == duration:
                    self.duration_combo.setCurrentIndex(i)
                    break
            
            # 绑定实体
            binding_type = ''
            binding_id = ''
            
            if self.ip_data.get('asset_id'):
                binding_type = 'asset'
                binding_id = self.ip_data['asset_id']
            elif self.ip_data.get('os_id'):
                binding_type = 'os'
                binding_id = self.ip_data['os_id']
            elif self.ip_data.get('system_id'):
                binding_type = 'system'
                binding_id = self.ip_data['system_id']
            elif self.ip_data.get('mw_id'):
                binding_type = 'middleware'
                binding_id = self.ip_data['mw_id']
            elif self.ip_data.get('oob_id'):
                binding_type = 'oob'
                binding_id = self.ip_data['oob_id']
            
            # 设置绑定类型
            for i in range(self.binding_type_combo.count()):
                if self.binding_type_combo.itemData(i) == binding_type:
                    self.binding_type_combo.setCurrentIndex(i)
                    break
            
            # 设置绑定ID
            if binding_id:
                self.binding_id_edit.setText(binding_id)
            
            # 附加信息
            self.os_name_edit.setText(self.ip_data.get('os_name', ''))
            self.hostname_edit.setText(self.ip_data.get('hostname', ''))
            self.description_edit.setText(self.ip_data.get('description', ''))
            
            # 如果是编辑模式，IP地址不可编辑
            if self.is_edit:
                self.ip_edit.setEnabled(False)
            
        except Exception as e:
            logger.error(f"加载数据失败: {str(e)}")
    
    def get_form_data(self) -> Dict[str, Any]:
        """获取表单数据"""
        data = {
            'ip': self.ip_edit.text().strip(),
            'subnet_mask': self.subnet_mask_edit.text().strip(),
            'vlan': self.utils.normalize_vlan(self.vlan_edit.text().strip()),
            'status': self.status_combo.currentData(),
            'purpose': self.purpose_combo.currentData(),
            'allocation_duration': self.duration_combo.currentData(),
            'os_name': self.os_name_edit.text().strip(),
            'hostname': self.hostname_edit.text().strip(),
            'description': self.description_edit.toPlainText().strip()
        }
        
        # 绑定实体信息
        binding_type = self.binding_type_combo.currentData()
        binding_id = self.binding_id_edit.text().strip()
        
        if binding_type and binding_id:
            if binding_type == 'asset':
                data['asset_id'] = binding_id
            elif binding_type == 'os':
                data['os_id'] = binding_id
            elif binding_type == 'system':
                data['system_id'] = binding_id
            elif binding_type == 'middleware':
                data['mw_id'] = binding_id
            elif binding_type == 'oob':
                data['oob_id'] = binding_id
        
        return data
    
    def validate_form(self) -> tuple[bool, str]:
        """验证表单数据"""
        data = self.get_form_data()
        
        # 使用工具类验证
        is_valid, error_msg = self.utils.validate_ip_data(data, self.is_edit)
        if not is_valid:
            return False, error_msg
        
        # 额外的业务验证
        
        # 检查IP冲突（新增时）
        if not self.is_edit:
            if self.service.check_ip_conflict(data['ip']):
                return False, f"IP地址 {data['ip']} 已存在"
        
        # 检查绑定实体（必须选择一个）
        binding_type = self.binding_type_combo.currentData()
        binding_id = self.binding_id_edit.text().strip()
        
        if not binding_type or not binding_id:
            return False, "必须选择一个绑定实体并输入对应的ID"
        
        # 验证实体ID是否存在
        if not self.validate_binding_entity(binding_type, binding_id):
            return False, f"绑定的{binding_type}ID {binding_id} 不存在"
        
        return True, ""
    
    def validate_binding_entity(self, binding_type: str, binding_id: str) -> bool:
        """验证绑定实体是否存在"""
        try:
            from src.app.database.database import get_database_manager
            from src.app.database.models import Asset, OperatingSystem, BusinessSystem, Middleware, OobManagement
            
            db = get_database_manager()
            with db.get_session() as session:
                if binding_type == "设备资产":
                    entity = session.query(Asset).filter(Asset.asset_id == binding_id).first()
                elif binding_type == "操作系统":
                    entity = session.query(OperatingSystem).filter(OperatingSystem.os_id == binding_id).first()
                elif binding_type == "业务系统":
                    entity = session.query(BusinessSystem).filter(BusinessSystem.system_id == binding_id).first()
                elif binding_type == "中间件":
                    entity = session.query(Middleware).filter(Middleware.mw_id == binding_id).first()
                elif binding_type == "带外管理":
                    entity = session.query(OobManagement).filter(OobManagement.oob_id == binding_id).first()
                else:
                    return False
                
                return entity is not None
                
        except Exception as e:
            logger.error(f"验证绑定实体失败: {str(e)}")
            return False
    
    def save_data(self) -> bool:
        """保存数据"""
        try:
            # 获取表单数据
            data = self.get_form_data()
            
            # 保存数据
            if self.is_edit:
                result = self.service.update_ip(self.ip_data['ip'], data)
            else:
                result = self.service.create_ip(data)
            
            if result['success']:
                # 发射数据保存信号
                self.data_saved.emit(result.get('data', data))
                return True
            else:
                self.show_error_message("保存失败", result['message'])
                return False
                
        except Exception as e:
            logger.error(f"保存数据失败: {str(e)}")
            self.show_error_message("保存失败", f"保存数据时发生错误: {str(e)}")
            return False
    
    def show_error_message(self, title: str, message: str):
        """显示错误消息"""
        from PyQt5.QtWidgets import QMessageBox
        QMessageBox.critical(self, title, message)
    
    def accept_data(self):
        """确定按钮点击事件 - 兼容BaseDialog"""
        try:
            # 验证表单
            is_valid, error_msg = self.validate_form()
            if not is_valid:
                self.show_error_message("验证失败", error_msg)
                return
            
            # 保存数据
            if self.save_data():
                self.accept()
                
        except Exception as e:
            logger.error(f"确定操作失败: {str(e)}")
            self.show_error_message("操作失败", f"操作时发生错误: {str(e)}")
    
    def accept(self):
        """接受对话框"""
        super().accept()